home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Internet / WWW / analog / Source / analform.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-09  |  13.2 KB  |  667 lines

  1. /* analform.c 1.9beta -- parse the output of the analog form interface */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6.  
  7. /* You must change the next line to indicate where the analog program lives */
  8.  
  9. #define COMMAND "/http/cgi-bin/analog"
  10. #define MAXARGLENGTH (2048)   /* should be plenty */
  11. #define OK (0)
  12. #define ERR (-1)
  13. #define STRLENGTH (64)
  14.  
  15. typedef int flag;
  16.  
  17. void unhttp(char *url)     /* converts back all http special characters */
  18. {
  19.   char *tempp;
  20.   char tempstr[MAXARGLENGTH];
  21.   int i;
  22.  
  23.   /* firstly, change +'s into spaces */
  24.  
  25.   for (i = strlen(url) - 1; i >= 0; i--) {
  26.     if (url[i] == '+')
  27.       url[i] = ' ';
  28.   }
  29.  
  30.   /* secondly change %7E to ~, etc. */
  31.  
  32.   tempp = url;
  33.   while ((tempp = strchr(tempp, '%')) != NULL) {
  34.     sscanf(tempp + 1, "%2x", &i);
  35.     if (i >= 0x20 && i < 0x7F) {
  36.       *tempp = i;
  37.       strcpy(tempstr, tempp + 3);
  38.       strcpy(tempp + 1, tempstr);
  39.       /* strcpy(tempp + 1, tempp + 3) may not be safe on all machines
  40.      (overlapping arguments) */
  41.     }
  42.     tempp++;
  43.   }
  44.  
  45. }
  46.  
  47. void genopts(FILE *thepipe, char name[9], int sortby, char *astr, char *cstr)
  48. {
  49.   fprintf(thepipe, "%sSORTBY ", name);
  50.   if (sortby == 3)
  51.     fprintf(thepipe, "RANDOM\n");
  52.   else if (sortby == 2)
  53.     fprintf(thepipe, "ALPHABETICAL\n");
  54.   else if (sortby == 1)
  55.     fprintf(thepipe, "BYTES\n");
  56.   else
  57.     fprintf(thepipe, "REQUESTS\n");
  58.   if (sortby == 1) {
  59.     if (cstr[0] != '\0')
  60.       fprintf(thepipe, "%sMINBYTES %s\n", name, cstr);
  61.   }
  62.   else {
  63.     if (astr[0] != '\0')
  64.       fprintf(thepipe, "%sMINREQS %s\n", name, astr);
  65.   }
  66. }
  67.  
  68. int main()
  69. {
  70.   extern void exit();
  71.  
  72.   /* the input */
  73.   char *argstring;
  74.   char *nextarg;
  75.   char *nextval;
  76.  
  77.   /* the variables that can be read in */
  78.   int xq = 0, mq = 0, Wq = 0, dq = 0, Dq = 0, hq = 0, oq = 0, Sq = 0;
  79.   int iq = 0, rq = 0, fq = 0, bq = 0, Bq = 0, cq = 0, eq = 0, Hq = 0;
  80.   char mg = '\0', Wg = '\0', dg = '\0', Dg = '\0', hg = '\0', Hg = '\0';
  81.   int os, Ss, is, rs, fs, Bs, bs;
  82.   int ou = 0;
  83.   char oa[STRLENGTH], Sa[STRLENGTH], ia[STRLENGTH], ra[STRLENGTH];
  84.   char fa[STRLENGTH], Ba[STRLENGTH], ba[STRLENGTH];
  85.   char oc[STRLENGTH], Sc[STRLENGTH], ic[STRLENGTH], rc[STRLENGTH];
  86.   char fc[STRLENGTH], Bc[STRLENGTH], bc[STRLENGTH];
  87.   int dirlevel;
  88.   char reqtype, reqlinks;
  89.   char *from = NULL, *to = NULL;
  90.   char *fonly = NULL, *fign = NULL;
  91.   char *honly = NULL, *hign = NULL;
  92.   char *org = NULL, *home = NULL;
  93.   char *logfile, *reflog, *browlog, *errlog, *cachefile;
  94.   char *TZ = NULL;
  95.   char TZenv[STRLENGTH];
  96.  
  97.   FILE *thepipe;
  98.   int ret;
  99.  
  100.   oa[0] = '\0';
  101.   Sa[0] = '\0';
  102.   ia[0] = '\0';
  103.   ra[0] = '\0';
  104.   fa[0] = '\0';
  105.   ba[0] = '\0';
  106.   Ba[0] = '\0';
  107.   oc[0] = '\0';
  108.   Sc[0] = '\0';
  109.   ic[0] = '\0';
  110.   rc[0] = '\0';
  111.   fc[0] = '\0';
  112.   bc[0] = '\0';
  113.   Bc[0] = '\0';
  114.  
  115.   if ((argstring = getenv("QUERY_STRING")) == NULL) {
  116.     printf("Content-type: text/plain\n\n");
  117.     printf("Error: cannot find environment variable QUERY_STRING\n");
  118.     exit(ERR);
  119.   }
  120.  
  121.   unhttp(argstring);
  122.  
  123.   nextarg = strtok(argstring, "&");
  124.  
  125.   while (nextarg != NULL) {
  126.     nextval = strchr(nextarg, '=') + 1;
  127.     if (nextval[0] != '\0') {
  128.       switch(nextarg[0]) {
  129.       case 'b':
  130.     switch(nextarg[1]) {
  131.     case 'a':
  132.       strcpy(ba, nextval);
  133.       break;
  134.     case 'b':
  135.       strcpy(ba, "-");
  136.       strcat(ba, nextval);
  137.       break;
  138.     case 'c':
  139.       strcpy(bc, nextval);
  140.       break;
  141.     case 'd':
  142.       strcpy(bc, "-");
  143.       strcat(bc, nextval);
  144.       break;
  145.     case 'q':
  146.       bq = atoi(nextval);
  147.       break;
  148.     case 's':
  149.       bs = atoi(nextval);
  150.       break;
  151.     }
  152.     break;
  153.       case 'B':
  154.     switch(nextarg[1]) {
  155.     case 'a':
  156.       strcpy(Ba, nextval);
  157.       break;
  158.     case 'b':
  159.       strcpy(ba, "-");
  160.       strcat(ba, nextval);
  161.       break;
  162.     case 'c':
  163.       strcpy(Bc, nextval);
  164.       break;
  165.     case 'd':
  166.       strcpy(Bc, "-");
  167.       strcat(Bc, nextval);
  168.       break;
  169.     case 'q':
  170.       Bq = atoi(nextval);
  171.       break;
  172.     case 's':
  173.       Bs = atoi(nextval);
  174.       break;
  175.     }
  176.     break;
  177.       case 'c':
  178.     cq = atoi(nextval);
  179.     break;
  180.       case 'd':
  181.     switch(nextarg[1]) {
  182.     case 'g':
  183.       dg = nextval[0];
  184.       break;
  185.     case 'q':
  186.       dq = 1;
  187.       break;
  188.     }
  189.     break;
  190.       case 'D':
  191.     switch(nextarg[1]) {
  192.     case 'g':
  193.       Dg = nextval[0];
  194.       break;
  195.     case 'q':
  196.       Dq = 1;
  197.       break;
  198.     }
  199.     break;
  200.       case 'e':
  201.     eq = atoi(nextval);
  202.     break;
  203.       case 'f':
  204.     switch(nextarg[1]) {
  205.     case 'a':
  206.       strcpy(fa, nextval);
  207.       break;
  208.     case 'b':
  209.       strcpy(fa, "-");
  210.       strcat(fa, nextval);
  211.       break;
  212.     case 'c':
  213.       strcpy(fc, nextval);
  214.       break;
  215.     case 'd':
  216.       strcpy(fc, "-");
  217.       strcat(fc, nextval);
  218.       break;
  219.     case 'i':
  220.       fign = nextval;
  221.       break;
  222.     case 'q':
  223.       fq = atoi(nextval);
  224.       break;
  225.     case 'r':
  226.       from = nextval;
  227.       break;
  228.     case 's':
  229.       fs = atoi(nextval);
  230.       break;
  231.     case 'y':
  232.       fonly = nextval;
  233.       break;
  234.     }
  235.     break;
  236.       case 'h':
  237.     switch(nextarg[1]) {
  238.     case 'g':
  239.       hg = nextval[0];
  240.       break;
  241.     case 'i':
  242.       hign = nextval;
  243.       break;
  244.     case 'o':
  245.       home = nextval;
  246.       break;
  247.     case 'q':
  248.       hq = 1;
  249.       break;
  250.     case 'y':
  251.       honly = nextval;
  252.       break;
  253.     }
  254.     break;
  255.       case 'H':
  256.     switch(nextarg[1]) {
  257.     case 'g':
  258.       Hg = nextval[0];
  259.       break;
  260.     case 'q':
  261.       Hq = atoi(nextval);
  262.       break;
  263.     }
  264.     break;
  265.       case 'i':
  266.     switch(nextarg[1]) {
  267.     case 'a':
  268.       strcpy(ia, nextval);
  269.       break;
  270.     case 'b':
  271.       strcpy(ia, "-");
  272.       strcat(ia, nextval);
  273.       break;
  274.     case 'c':
  275.       strcpy(ic, nextval);
  276.       break;
  277.     case 'd':
  278.       strcpy(ic, "-");
  279.       strcat(ic, nextval);
  280.       break;
  281.     case 'e':
  282.       dirlevel = atoi(nextval);
  283.       break;
  284.     case 'q':
  285.       iq = atoi(nextval);
  286.       break;
  287.     case 's':
  288.       is = atoi(nextval);
  289.       break;
  290.     }
  291.     break;
  292.       case 'l':
  293.     switch(nextarg[1]) {
  294.     case 'b':
  295.       browlog = nextval;
  296.       break;
  297.     case 'c':
  298.       cachefile = nextval;
  299.       break;
  300.     case 'e':
  301.       errlog = nextval;
  302.       break;
  303.     case 'f':
  304.       reflog = nextval;
  305.       break;
  306.     case 'o':
  307.       logfile = nextval;
  308.       break;
  309.     }
  310.     break;
  311.       case 'm':
  312.     switch(nextarg[1]) {
  313.     case 'g':
  314.       mg = nextval[0];
  315.       break;
  316.     case 'q':
  317.       mq = 1;
  318.       break;
  319.     }
  320.     break;
  321.       case 'o':
  322.     switch(nextarg[1]) {
  323.     case 'a':
  324.       strcpy(oa, nextval);
  325.       break;
  326.     case 'b':
  327.       strcpy(oa, "-");
  328.       strcat(oa, nextval);
  329.       break;
  330.     case 'c':
  331.       strcpy(oc, nextval);
  332.       break;
  333.     case 'd':
  334.       strcpy(oc, "-");
  335.       strcat(oc, nextval);
  336.       break;
  337.     case 'q':
  338.       oq = atoi(nextval);
  339.       break;
  340.     case 'r':
  341.       org = nextval;
  342.       break;
  343.     case 's':
  344.       os = atoi(nextval);
  345.       break;
  346.     case 'u':
  347.       ou = atoi(nextval);
  348.       break;
  349.     }
  350.     break;
  351.       case 'r':
  352.     switch(nextarg[1]) {
  353.     case 'a':
  354.       strcpy(ra, nextval);
  355.       break;
  356.     case 'b':
  357.       strcpy(ra, "-");
  358.       strcat(ra, nextval);
  359.       break;
  360.     case 'c':
  361.       strcpy(rc, nextval);
  362.       break;
  363.     case 'd':
  364.       strcpy(rc, "-");
  365.       strcat(rc, nextval);
  366.       break;
  367.     case 'l':
  368.       reqlinks = nextval[0];
  369.       break;
  370.     case 'q':
  371.       rq = atoi(nextval);
  372.       break;
  373.     case 's':
  374.       rs = atoi(nextval);
  375.       break;
  376.     case 't':
  377.       reqtype = nextval[0];
  378.       break;
  379.     }
  380.     break;
  381.       case 'S':
  382.     switch(nextarg[1]) {
  383.     case 'a':
  384.       strcpy(Sa, nextval);
  385.       break;
  386.     case 'b':
  387.       strcpy(Sa, "-");
  388.       strcat(Sa, nextval);
  389.       break;
  390.     case 'c':
  391.       strcpy(Sc, nextval);
  392.       break;
  393.     case 'd':
  394.       strcpy(Sc, "-");
  395.       strcat(Sc, nextval);
  396.       break;
  397.     case 'q':
  398.       Sq = atoi(nextval);
  399.       break;
  400.     case 's':
  401.       Ss = atoi(nextval);
  402.       break;
  403.     }
  404.     break;
  405.       case 't':
  406.     to = nextval;
  407.     break;
  408.       case 'T':
  409.     TZ = nextval;
  410.     break;
  411.       case 'W':
  412.     switch(nextarg[1]) {
  413.     case 'g':
  414.       Wg = nextval[0];
  415.       break;
  416.     case 'q':
  417.       Wq = 1;
  418.       break;
  419.     }
  420.     break;
  421.       case 'x':
  422.     xq = 1;
  423.     break;
  424.       }
  425.     }
  426.     nextarg = strtok((char *)NULL, "&");
  427.   }
  428.  
  429.   /* OK, so we've read everything in, now send it to the program */
  430.   
  431.   if (TZ != NULL) {
  432.     strcpy(TZenv, "TZ=");
  433.     strcat(TZenv, TZ);
  434.     putenv(TZenv);
  435.   }
  436.  
  437.   if ((thepipe = popen(COMMAND " +g-", "w")) == NULL) {
  438.     printf("Content-type: text/plain\n\n");
  439.     printf("Error: cannot start analog program at %s\n", COMMAND);
  440.   }
  441.  
  442.   else {
  443.     printf("Content-type: text/html\n\n");
  444.     fflush(stdout);
  445.  
  446.     fprintf(thepipe, "OUTFILE stdout\n");
  447.  
  448.     if (xq < 2)
  449.       fprintf(thepipe, "GENERAL %s\n", xq?"ON":"OFF");
  450.     if (mq < 2)
  451.       fprintf(thepipe, "MONTHLY %s\n", mq?"ON":"OFF");
  452.     if (Wq < 2)
  453.       fprintf(thepipe, "WEEKLY %s\n", Wq?"ON":"OFF");
  454.     if (dq < 2)
  455.       fprintf(thepipe, "DAILY %s\n", dq?"ON":"OFF");
  456.     if (Dq < 2)
  457.       fprintf(thepipe, "FULLDAILY %s\n", Dq?"ON":"OFF");
  458.     if (hq < 2)
  459.       fprintf(thepipe, "HOURLY %s\n", hq?"ON":"OFF");
  460.     if (Hq < 2)
  461.       fprintf(thepipe, "FULLHOURLY %s\n", Hq?"ON":"OFF");
  462.     if (oq < 2)
  463.       fprintf(thepipe, "DOMAIN %s\n", oq?"ON":"OFF");
  464.     if (Sq < 2)
  465.       fprintf(thepipe, "FULLHOSTS %s\n", Sq?"ON":"OFF");
  466.     if (iq < 2)
  467.       fprintf(thepipe, "DIRECTORY %s\n", iq?"ON":"OFF");
  468.     if (rq < 2)
  469.       fprintf(thepipe, "REQUEST %s\n", rq?"ON":"OFF");
  470.     if (bq < 2)
  471.       fprintf(thepipe, "BROWSER %s\n", bq?"ON":"OFF");
  472.     if (Bq < 2)
  473.       fprintf(thepipe, "FULLBROWSER %s\n", Bq?"ON":"OFF");
  474.     if (cq < 2)
  475.       fprintf(thepipe, "STATUS %s\n", bq?"ON":"OFF");
  476.     if (eq < 2)
  477.       fprintf(thepipe, "ERROR %s\n", bq?"ON":"OFF");
  478.     if (fq < 2)
  479.       fprintf(thepipe, "REFERER %s\n", bq?"ON":"OFF");
  480.  
  481.     if (mq && mg != '\0')
  482.       fprintf(thepipe, "MONTHGRAPH %c", mg);
  483.     if (Wq && Wg != '\0')
  484.       fprintf(thepipe, "WEEKGRAPH %c", Wg);
  485.     if (hq && hg != '\0')
  486.       fprintf(thepipe, "HOURGRAPH %c", hg);
  487.     if (Hq && Hg != '\0')
  488.       fprintf(thepipe, "FULLHOURGRAPH %c", Hg);
  489.     if (dq && dg != '\0')
  490.       fprintf(thepipe, "DAYGRAPH %c", dg);
  491.     if (Dq && Dg != '\0')
  492.       fprintf(thepipe, "FULLDAYGRAPH %c", Dg);
  493.  
  494.     if (oq)
  495.       genopts(thepipe, "DOM", os, oa, oc);
  496.     if (Sq)
  497.       genopts(thepipe, "HOST", Ss, Sa, Sc);
  498.     if (iq) {
  499.       genopts(thepipe, "DIR", is, ia, ic);
  500.       fprintf(thepipe, "DIRLEVEL %d\n", dirlevel);
  501.     }
  502.     if (rq) {
  503.       genopts(thepipe, "REQ", rs, ra, rc);
  504.       fprintf(thepipe, "REQTYPE %s\n", reqtype=='f'?"ALL":"PAGES");
  505.       fprintf(thepipe, "PAGELINKS %s\n", reqlinks=='f'?"ALL":(reqlinks=='p'?"ON":"OFF"));
  506.     }
  507.     if (bq)
  508.       genopts(thepipe, "BROW", bs, ba, bc);
  509.     if (Bq)
  510.       genopts(thepipe, "FULLBROW", Bs, Ba, Bc);
  511.     if (fq)
  512.       genopts(thepipe, "REF", fs, fa, fc);
  513.  
  514.     fprintf(thepipe, "OUTPUT %s\n", ou?"ASCII":"HTML");
  515.  
  516.     if (from != NULL)
  517.       fprintf(thepipe, "FROM %s\n", from);
  518.     if (to != NULL)
  519.       fprintf(thepipe, "TO %s\n", to);
  520.     if (org != NULL)
  521.       fprintf(thepipe, "HOSTNAME \"%s\"\n", org);
  522.     if (home != NULL)
  523.       fprintf(thepipe, "HOSTURL %s\n", home);
  524.     else
  525.       fprintf(thepipe, "HOSTURL -\n");
  526.     
  527.     /* That just leaves the only's and ignore's and logfiles, which are a bit
  528.        more complicated as we have to parse them still. Recycle 'nextarg'. */
  529.  
  530.     nextarg = strtok(fonly, " ,");   /* split at spaces and commas */
  531.     while (nextarg != NULL) {
  532.       fprintf(thepipe, "FILEINCLUDE %s\n", nextarg);
  533.       nextarg = strtok((char *)NULL, " ,");
  534.     }
  535.  
  536.     nextarg = strtok(fign, " ,");
  537.     while (nextarg != NULL) {
  538.       fprintf(thepipe, "FILEEXCLUDE %s\n", nextarg);
  539.       nextarg = strtok((char *)NULL, " ,");
  540.     }
  541.  
  542.     nextarg = strtok(honly, " ,");
  543.     while (nextarg != NULL) {
  544.       fprintf(thepipe, "HOSTINCLUDE %s\n", nextarg);
  545.       nextarg = strtok((char *)NULL, " ,");
  546.     }
  547.  
  548.     nextarg = strtok(hign, " ,");
  549.     while (nextarg != NULL) {
  550.       fprintf(thepipe, "HOSTEXCLUDE %s\n", nextarg);
  551.       nextarg = strtok((char *)NULL, " ,");
  552.     }
  553.  
  554.     nextarg = strtok(browlog, " ,");
  555.     while (nextarg != NULL) {
  556.       fprintf(thepipe, "BROWLOG %s\n", nextarg);
  557.       nextarg = strtok((char *)NULL, " ,");
  558.     }
  559.  
  560.     nextarg = strtok(errlog, " ,");
  561.     while (nextarg != NULL) {
  562.       fprintf(thepipe, "ERRLOG %s\n", nextarg);
  563.       nextarg = strtok((char *)NULL, " ,");
  564.     }
  565.  
  566.     nextarg = strtok(reflog, " ,");
  567.     while (nextarg != NULL) {
  568.       fprintf(thepipe, "REFLOG %s\n", nextarg);
  569.       nextarg = strtok((char *)NULL, " ,");
  570.     }
  571.  
  572.     nextarg = strtok(logfile, " ,");
  573.     while (nextarg != NULL) {
  574.       fprintf(thepipe, "LOGFILE %s\n", nextarg);
  575.       nextarg = strtok((char *)NULL, " ,");
  576.     }
  577.  
  578.     nextarg = strtok(cachefile, " ,");
  579.     while (nextarg != NULL) {
  580.       fprintf(thepipe, "CACHEFILE %s\n", nextarg);
  581.       nextarg = strtok((char *)NULL, " ,");
  582.     }
  583.  
  584.   }
  585.  
  586.   fflush(thepipe);
  587.   ret = pclose(thepipe);
  588.   if (ret != 0) {
  589.     printf("Analog failed to run or returned an error code.\n");
  590.     printf("Maybe your server's error log will give a clue why.\n");
  591.   }
  592.   fflush(stdout);
  593.   exit(ret);
  594.  
  595. }
  596. extern int putenv(char *newval)
  597. {
  598.     extern char **environ;
  599.  
  600.     static int firstTime = 1;
  601.     char **ep;
  602.     char *cp;
  603.     int esiz;
  604.     char *np;
  605.  
  606.     if (!(np = strchr(newval, '=')))
  607.     return 1;
  608.     *np = '\0';
  609.  
  610.     /* look it up */
  611.     for (ep=environ ; *ep ; ep++)
  612.     {
  613.     /* this should always be true... */
  614.     if (cp = strchr(*ep, '='))
  615.     {
  616.         *cp = '\0';
  617.         if (!strcmp(*ep, newval))
  618.         {
  619.         /* got it! */
  620.         *cp = '=';
  621.         break;
  622.         }
  623.         *cp = '=';
  624.     }
  625.     else
  626.     {
  627.         *np = '=';
  628.         return 1;
  629.     }
  630.     }
  631.  
  632.     *np = '=';
  633.     if (*ep)
  634.     {
  635.     /* the string was already there: just replace it with the new one */
  636.     *ep = newval;
  637.     return 0;
  638.     }
  639.  
  640.     /* expand environ by one */
  641.     for (esiz=2, ep=environ ; *ep ; ep++)
  642.     esiz++;
  643.     if (firstTime)
  644.     {
  645.     char **epp;
  646.     char **newenv;
  647.     if (!(newenv = malloc(esiz * sizeof(char *))))
  648.         return 1;
  649.    
  650.     for (ep=environ, epp=newenv ; *ep ;)
  651.         *epp++ = *ep++;
  652.     *epp++ = newval;
  653.     *epp = (char *) 0;
  654.     environ = newenv;
  655.     }
  656.     else
  657.     {
  658.     if (!(environ = realloc(environ, esiz * sizeof(char *))))
  659.         return 1;
  660.     environ[esiz - 2] = newval;
  661.     environ[esiz - 1] = (char *) 0;
  662.     firstTime = 0;
  663.     }
  664.  
  665.     return 0;
  666. }
  667.